/**
 * @file es_drv.c
 *
 * @brief 实现驱动层的读写接口。
 *
 * @author bagy
 *
 * @version V1.0
 *
 * @date 2024-05-14
 */

#include "es_drv.h"

/**
 * @brief 读取设备驱动数据
 *
 * @param fd 设备驱动号
 * @param buffer 保存读取的设备驱动数据
 * @param size 读取的设备驱动数据长度
 *
 * @return ES_EOK 读取完成
 */
ES_INT32 es_drv_read(ES_INT32 fd, ES_VOID *buffer, ES_INT32 size)
{
	if((fd <= 0) || (size <= 0))
		return ES_EINVAL;

	ES_INT32 ret = 0;
    es_drv_t *drv = es_drv_find(fd);

    if(drv)
    {
        if(drv->drv_ops->read)
        {
        	ret = drv->drv_ops->read(drv, buffer, size);
        }
        else
        {
        	ret = ES_EINVAL;
        }
    }
    else
    {
    	ret = ES_EINVAL;
    }

    return ret;
}

/**
 * @brief 向设备驱动写入数据
 *
 * @param fd 设备驱动号
 * @param buffer 写入设备驱动的数据
 * @param size 写入设备驱动的数据长度
 *
 * @return ES_EOK 写入完成
 */
ES_INT32 es_drv_write(ES_INT32 fd, ES_CONST ES_VOID *buffer, ES_INT32 size)
{
	if((fd <= 0) || (size <= 0))
		return ES_EINVAL;

    es_drv_t *drv = es_drv_find(fd);

    if(drv)
    {
        if(drv->drv_ops->write)
        {
            return drv->drv_ops->write(drv, buffer, size);
        }
    }
    return ES_EINVAL;
}

/**
 * @brief 向设备驱动写入数据
 *
 * @param fd 设备驱动号
 * @param buffer 写入设备驱动的数据
 * @param size 写入设备驱动的数据长度
 *
 * @return ES_EOK 读取完成
 */
ES_INT32 es_drv_ioctl(ES_INT32 fd, ES_INT32 cmd, ES_VOID *args)
{
	if((fd <= 0) || (args == NULL))
		return ES_EINVAL;

    es_drv_t *drv = es_drv_find(fd);

    if(drv)
    {
        if(drv->drv_ops->ioctl)
        {
            return drv->drv_ops->ioctl(drv, cmd, args);
        }
    }
    return ES_EINVAL;
}

/**
 * @brief 自动初始化函数。
 *
 * @details 通过自定义段的起始和结束地址，遍历段中的每个函数，实现自动初始化。
 */
ES_VOID es_drv_init(ES_VOID)
{
	extern es_init_fn_t _es_drv_init_start;
	extern es_init_fn_t _es_drv_init_end;

    /* Auto-initialization */
    for (es_init_fn_t *fn = &_es_drv_init_start; fn < &_es_drv_init_end; fn++)
    {
        (*fn)();
    }
}

